package agentes09.geografia;

/**
 * Almacena las distancias entre las ciudades del juego. Si dos ciudades no están
 * conectadas directamente, la distancia es <tt>Double.NaN</tt> (Not a Number).
 * @author Briseida Sarasola
 * @version 0.1
 */
public class Distancias {

    static Distancias singleton;
    static double[][] distancias;

    protected Distancias() {
        distancias = new double[8][8];

        for (int i = 0; i < distancias.length; i++) {
            for (int j = 0; j < distancias.length; j++) {
                distancias[i][j] = Double.NaN;
            }
        }

        // Asignar las distancias conocidas
        distancias[(Ciudad.GRANADA).ordinal()][(Ciudad.ALMERIA).ordinal()] = 166;
        distancias[(Ciudad.MALAGA).ordinal()][(Ciudad.ALMERIA).ordinal()] = 210;
        distancias[(Ciudad.MALAGA).ordinal()][(Ciudad.CADIZ).ordinal()] = 268;
        distancias[(Ciudad.SEVILLA).ordinal()][(Ciudad.CADIZ).ordinal()] = 145;
        distancias[(Ciudad.GRANADA).ordinal()][(Ciudad.CORDOBA).ordinal()] = 200;
        distancias[(Ciudad.JAEN).ordinal()][(Ciudad.CORDOBA).ordinal()] = 105;
        distancias[(Ciudad.MALAGA).ordinal()][(Ciudad.CORDOBA).ordinal()] = 172;
        distancias[(Ciudad.SEVILLA).ordinal()][(Ciudad.CORDOBA).ordinal()] = 133;
        distancias[(Ciudad.JAEN).ordinal()][(Ciudad.GRANADA).ordinal()] = 134;
        distancias[(Ciudad.MALAGA).ordinal()][(Ciudad.GRANADA).ordinal()] = 164;
        distancias[(Ciudad.SEVILLA).ordinal()][(Ciudad.GRANADA).ordinal()] = 269;
        distancias[(Ciudad.SEVILLA).ordinal()][(Ciudad.HUELVA).ordinal()] = 96;
        distancias[(Ciudad.MALAGA).ordinal()][(Ciudad.SEVILLA).ordinal()] = 215;


        // Inicializar el resto de distancias
        for (int i = 0; i < distancias.length; i++) {
            for (int j = 0; j < distancias.length; j++) {
                if (i == j) {
                    distancias[i][j] = 0;
                } else if (distancias[j][i] != Double.NaN) {
                    distancias[i][j] = distancias[j][i];
                }
            }
        }
    }

    public static Distancias getInstancia() {
        if (singleton == null) {
            singleton = new Distancias();
        }
        return singleton;
    }

    /**
     * Devuelve la distancia entre dos ciudades.
     * @param origen la ciudad de origen
     * @param destino la ciudad destino
     * @return la distancia entre ambas; si no están conectadas directamente, se
     * devuelve NaN
     */
    public static double getDistancia(Ciudad origen, Ciudad destino) {
        return distancias[origen.ordinal()][destino.ordinal()];
    }

    @Override
    public String toString() {
        String res = "";
        
        for (Ciudad c1 : Ciudad.values()) {
            for (Ciudad c2 : Ciudad.values()) {
                res += getDistancia(c1, c2) + " ";
            }
            res +="\n";
        }
        return res;
    }
}
